package com.yunhe.common.util;

import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName ReflectUtil
 * @Description TODO
 * @Author HeTao
 * @Date 2021/2/26 18:14
 * @Version 1.0
 **/
public class ReflectUtil {

    //类属性转get方法名
    public static String getMethodName(String propertyName) {
        String methodEnd = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        methodEnd="get"+methodEnd;
        return methodEnd;
    }

    //类属性转set方法名
    public static String setMethodName(String propertyName) {
        String methodEnd = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        methodEnd="set"+methodEnd;
        return methodEnd;
    }

    //获取包含父类的所有Field
    public static Field getDeclaredField(Class clazz , String fieldName) {
        if (!StringUtil.isEmpty(fieldName)) {
            while (!Object.class.equals(clazz)) {
                Field resultField = Arrays.stream(clazz.getDeclaredFields()).filter(field -> fieldName.equals(field.getName())).findAny().orElse(null);
                if (resultField == null){
                    clazz = clazz.getSuperclass();
                }else {
                    return resultField;
                }
            }
            return null;
        }
        return null;
    }

    //获取包含父类的所有Field
    public static List<Field> getDeclaredFields(Class clazz) {
        List<Field> fields = new ArrayList<>();
        while (!Object.class.equals(clazz)) {
            fields.addAll(Arrays.stream(clazz.getDeclaredFields()).collect(Collectors.toList()));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

    //获取Field的值
    public static String getFieldValue(String fieldName, Object obj) {
        Class<?> clazz = obj.getClass();
        Field field = ReflectUtil.getDeclaredField(clazz, fieldName);
        return getFieldValue(field,obj);
    }

    //获取Field的值
    public static String getFieldValue(Field field, Object obj) {
        Class<?> clazz = obj.getClass();
        if (field == null) {
            return null;
        }
        ReflectionUtils.makeAccessible(field);
        String methodName = ReflectUtil.getMethodName(field.getName());//获得get方法
        try {
            Method getMethod = clazz.getMethod(methodName);
            String result =  getMethod.invoke(obj, new Object[]{}) + "";
            if ("null".equals(result)){
                return null;
            }else {
                return result;
            }
        } catch (Exception e) {
            return null;
        }
    }

    //赋予Field值
    public static void setFieldValue(String fieldName, Object value, Object obj) {
        Class<?> clazz = obj.getClass();
        Field field = ReflectUtil.getDeclaredField(clazz, fieldName);
        setFieldValue(field,value,obj);
    }

    //赋予Field值
    public static void setFieldValue(Field field, Object value, Object obj) {
        if (field != null) {
            ReflectionUtils.makeAccessible(field);
            try {
                field.set(obj, value);
            } catch (Exception e) {
                System.out.println("field:"+field+",value:"+value);
            }
        }
    }

    //获取List中的泛型类型
    public static Class<?> getActualType(Field field) {
        // 当前集合的泛型类型
        Type genericType = field.getGenericType();
        if (null == genericType) {
            return null;
        }
        if (genericType instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) genericType;
            // 得到泛型里的class类型对象
            return (Class<?>) pt.getActualTypeArguments()[0];
        }
        return null;
    }
}
